/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ControlLayer;

import DBLayer.DBEmployee;
import ModelLayer.Actor;
import ModelLayer.Role;
import java.io.InvalidObjectException;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.swing.event.EventListenerList;

/**
 *
 * @author Moulde
 */
public class GlobalInstances
{
    private Actor employee;
    private Date timeOfValidation;
    private boolean isDebug = false;
    private final int timeoutMinutes = 30;
    private Actor customer;
    
    ///// Event
    protected EventListenerList listenerList = new EventListenerList();

    ///// Singleton
    private static GlobalInstances instance;

    public static GlobalInstances getInstance()
    {
        if (instance == null)
        {
            instance = new GlobalInstances();
        }

        return instance;
    }

    private GlobalInstances()
    {
    }

    //register listeners
    public void addILoginStateChangedEventListener(ILoginStateChangedEventListener listener)
    {
        listenerList.add(ILoginStateChangedEventListener.class, listener);
    }

    public void addICustomerPickedEventListener(ICustomerPickedEventListener listener)
    {
        listenerList.add(ICustomerPickedEventListener.class, listener);
    }

    //unregister listeners
    public void removeILoginStateChangedEventListener(ILoginStateChangedEventListener listener)
    {
        listenerList.remove(ILoginStateChangedEventListener.class, listener);
    }

    public void removeICustomerPickedEventListener(ICustomerPickedEventListener listener)
    {
        listenerList.remove(ICustomerPickedEventListener.class, listener);
    }

    //Fire events
    private void fireLoginStateChangedEvent(LoginStateChangedEvent evt)
    {
        Object[] listeners = listenerList.getListenerList();
        for (int i = 0; i < listeners.length; i += 2)
        {
            if (listeners[i] == ILoginStateChangedEventListener.class)
            {
                ((ILoginStateChangedEventListener) listeners[i + 1]).LoginStateChangedEventOccurred(evt);
            }
        }
    }

    private void fireCustomerPickedEvent(CustomerPickedEvent evt)
    {
        Object[] listeners = listenerList.getListenerList();
        for (int i = 0; i < listeners.length; i += 2)
        {
            if (listeners[i] == ICustomerPickedEventListener.class)
            {
                ((ICustomerPickedEventListener) listeners[i + 1]).CustomerPickedEventOccurred(evt);
            }
        }
    }

    public Actor getCurrentCustomer()
    {
        return customer;
    }

    public void setCurrentCustomer(Actor customer) throws InvalidObjectException
    {
        if (!customer.isRolePresent(Role.Customer))
        {
            throw new InvalidObjectException("Den valgte actor er ikke kunde");
        }

        this.customer = customer;
        fireCustomerPickedEvent(new CustomerPickedEvent(this, customer));
    }

    /**
     * Get the value of isDebug
     *
     * @return the value of isDebug
     */
    public boolean IsDebug()
    {
        return isDebug;
    }

    /**
     * Set the value of isDebug
     *
     * @param isDebug new value of isDebug
     */
    public void setIsDebug(boolean isDebug)
    {
        this.isDebug = isDebug;
    }

    public Actor getCurrentEmployee()
    {
        //update();
        return employee;
    }

    public boolean logIn(String username, String password)
    {
        //update();

        if (isLoggedIn())
        {
            return true;
        }

        DBEmployee dbEmployee = new DBEmployee();

        ActorController actorController = new ActorController();
        Actor actor = actorController.validateEmployee(username, password);
        if (actor != null)
        {
            employee = actor;
            timeOfValidation = new Date();
            fireLoginStateChangedEvent(new LoginStateChangedEvent(this, employee, LoginStateChangedEvent.LoggedInState));
            System.out.println(employee.getName() + " logged in");
            return true;
        }
        else
        {
            return false;
        }
    }

    public void logOut()
    {
        fireLoginStateChangedEvent(new LoginStateChangedEvent(this, employee.clone(), LoginStateChangedEvent.LoggedOutState));
        employee = null;
    }

    public boolean isLoggedIn()
    {
        //update();
        return employee != null;
    }

    /**
     * Checks if the login was done more than 30 minutes ago, and if yes, resets the employee.
     *
     * 
     */
    private void update()
    {
        if (isDebug)
        {
            ActorController actorController = new ActorController();
            employee = actorController.dbActor.getObject(1); //.dbEmployee.getObject(1);
            timeOfValidation = new Date();
            return;
        }

        if (employee == null)
        {
            return;
        }

        Date now = new Date();
        GregorianCalendar cal = new GregorianCalendar();
        cal.setTime(now);
        cal.roll(GregorianCalendar.MINUTE, timeoutMinutes * -1);

        if (timeOfValidation.after(cal.getTime()))
        {
            fireLoginStateChangedEvent(new LoginStateChangedEvent(this, employee.clone(), LoginStateChangedEvent.LoggedOutState));
            employee = null;
        }
    }
}
